package com.onpositive.units;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import org.w3c.dom.Element;

import com.onpositive.knowledge.model.values.IHasValue;
import com.onpositive.semantic.model.api.realm.IRealm;
import com.onpositive.semantic.model.api.realm.Realm;

public class ParsedSection extends ParsedValue {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 325523690600850161L;

	public static final String ID = "text-section" ;
	
	final String name ;
	final String parentSectionName ;
	final TextContent textContent ;
	
	
	private String value ;
	//private int order = 0 ;//non-xml metadata used to remember in-document order
	
	public ParsedSection( String name, String parentSectionName, ArrayList<String> sectionContent, TextContent tc, String comment )
	{
		super(comment) ;
		this.textContent = tc ;
		this.name = name ;
		this.parentSectionName = parentSectionName ;
		StringBuilder bld = new StringBuilder() ;
		int s = sectionContent.size() ;

		for( int i = 0 ; i < s ; i++ ){
			bld.append( sectionContent.get(i).trim() ) ;
			bld.append( "\n\n" );
		}
		
		int l = bld.length();
		if( l > 0 )
			bld.delete( l-2, l ) ;
		
		String valueString = bld.toString().replaceAll("\\n{2,}", "\\\n\\\n").trim();
		this.value = valueString ;	
	}
	
	public ParsedSection( String name, String parentSectionName, String valueString, TextContent tc, String comment )
	{
		super(comment) ;
		this.textContent = tc ;
		this.name = name ;
		this.parentSectionName = parentSectionName ;
		this.value = valueString ;	
	}
	
	public ParsedSection( ParsedValue pv, String comment, TextContent tc )
	{
		super( comment ) ;		
		ParsedSection other = (ParsedSection) pv ;
		this.name = other.name ;
		this.parentSectionName = other.parentSectionName ;
		this.value = other.value ;
		this.textContent = tc ;
	}
	
	public ParsedSection( ParsedSection other, Object value, String comment )
	{
		super( comment ) ;	
		this.name = other.name ;
		this.parentSectionName = other.parentSectionName ;
		this.value = (String) value ;
		this.textContent = null ;
	}
	
	public ParsedSection( Element element, TextContent tc )
	{
		super(element);
		this.name = element.getAttribute("name").trim() ;
		this.value = element.getAttribute("value").trim() ;
		String pr = element.getAttribute("parent") ;
//		if( pr.length() != 0  )
			this.parentSectionName = pr ;
			
		this.textContent = tc ;
	}
	
	public ParsedSection( String fullContent, TextContent tc, String comment)
	{
		super(comment);
		this.textContent = tc ;
		int ind = fullContent.indexOf('\n') ;
		ind = fullContent.indexOf('\n',ind+1) ;
		String info = fullContent.substring( 0,ind ) ;
		ind++ ;
		
		this.value = fullContent.substring(ind) ;
		
		ind = info.indexOf("parent=") ;
		String s1 = info.substring(0,ind) ;
		String s2 = info.substring(ind) ;
		
		ind = s1.indexOf('=') ;
		this.name = s1.substring(ind+1).trim() ;
		
		ind = s2.indexOf('=') ;
		this.parentSectionName = s2.substring(ind+1).trim() ;
	}
					
	
	@Override
	public Object value() {
		return value;
	}
	@Override
	public Object describer() {
		return String.class;
	}
	@Override
	public void writeValue(Element element)
	{
		super.writeValuePartial(element) ;
		
		element.setAttribute("name" , this.name );
		element.setAttribute("parent" , this.parentSectionName != null ? this.parentSectionName : "" );
		element.setAttribute("value" , this.value );
	}
	@Override
	public String getId() {
		return ID;
	}
	
//	private void setOrder( int order)
//	{
//		this.order = order ;
//	}
//	
//	private int getOrder()
//	{
//		return this.order ;
//	}

	@Override
	public String getValueAsString() {
		StringBuilder bld = new StringBuilder() ;
		bld.append("name=" );
		bld.append( name );
		bld.append("\n") ;
		bld.append("parent=" );
		bld.append( parentSectionName );
		bld.append("\n" );
		bld.append( value );
		return bld.toString() ;
	}

	@Override
	public void setValue(Object obj) {
		// TODO Auto-generated method stub
		
	}


	public IRealm<ParsedSection> getParent() {
		
		Realm<ParsedSection> tpe = new Realm<ParsedSection>();
		ParsedSection parent = textContent.getSection( parentSectionName ) ;
		if( parent != null )
			tpe.add(parent) ;		
		return tpe;
	}


	public String getName() {
		return name;
	}


	public String getParentSectionName() {
		return parentSectionName;
	}

	public TextContent getTextContent() {
		return textContent;
	}

	@Override
	public String toString(){
		return this.getName() ;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime
				* result
				+ ((parentSectionName == null) ? 0 : parentSectionName
						.hashCode());

		result = prime * result + ((value == null) ? 0 : value.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ParsedSection other = (ParsedSection) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (parentSectionName == null) {
			if (other.parentSectionName != null)
				return false;
		} else if (!parentSectionName.equals(other.parentSectionName))
			return false;
		if (textContent == null) {
			if (other.textContent != null)
				return false;
		}
		if (value == null) {
			if (other.value != null)
				return false;
		} else if (!value.equals(other.value))
			return false;
		return true;
	}

	@Override
	public IHasValue clone(Object value, String comment) {
		if( !(value instanceof String) )
			return null ;
		if( comment == null )
			comment = this.getComment() ;
		return new ParsedSection(this, value, comment);
	}

	@Override
	public <T> Collection<T> getValues(Class<T> vs) {
		return Collections.emptySet();
	}
	
	



}
